package com.synjones.printer.billPrinter;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;

import com.synjones.entry.SignPerson;
import com.synjones.idcardusb_reader.R;

import net.posprinter.posprinterface.IMyBinder;
import net.posprinter.posprinterface.ProcessData;
import net.posprinter.posprinterface.TaskCallback;
import net.posprinter.service.PosprinterService;
import net.posprinter.utils.BitmapProcess;
import net.posprinter.utils.BitmapToByteData;
import net.posprinter.utils.DataForSendToPrinterPos58;
import net.posprinter.utils.PosPrinterDev;
import net.posprinter.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

import static android.content.Context.BIND_AUTO_CREATE;

public class BillPrinter {

    public static final String TAG = "BillPrinter";

    private Context context;

    private IMyBinder myBinder;

    private boolean connected;

    //传输反馈信息（将异步信息变为同步信息）
    private LinkedBlockingQueue<String> stateTransportQueue = new LinkedBlockingQueue<>(1);

    private ServiceConnection mSerconnection= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder= (IMyBinder) service;
            stateTransportQueue.offer("serviceConnSuccess");
            Log.i(TAG,"BillPrinterService connect success");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG,"BillPrinterService disconnect success");
            stateTransportQueue.offer("serviceConnFail");
        }
    };


    public BillPrinter(Context context) {
        this.context = context;
    }

    /**
     * 连接打印服务
     * call on onCreate time
     */
    public boolean connectPrinterService(){

        //bind service，get imyBinder
        Intent intent =new Intent(context, PosprinterService.class);
        context.bindService(intent,mSerconnection,BIND_AUTO_CREATE);
        try {
            return stateTransportQueue.take().equals("serviceConnSuccess");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 连接打印机
     * @return 是否连接成功
     */
    @WorkerThread
    public Boolean connectDevice(){

        List<String> usbDevices = PosPrinterDev.GetUsbPathNames(context);
        if (usbDevices == null) return  false;
        for (String usbDevice: usbDevices) {
            myBinder.ConnectUsbPort(context.getApplicationContext(), usbDevice, new TaskCallback() {
                @Override
                public void OnSucceed() {
                    stateTransportQueue.offer("connUsbSuccess");
                }

                @Override
                public void OnFailed() {
                    stateTransportQueue.offer("connUsbFail");
                }
            });
            try {
                connected = stateTransportQueue.take().equals("connUsbSuccess");
                return connected;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return false;
    }




    /**
     * 打印标题文字
     */
    @WorkerThread
    public boolean printPersonInfo(final SignPerson signPerson, final String presenterName, final String presenterNo){

        if (connected){
            Bitmap bitmapLog1 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.print_log1);
            Bitmap bitmapLog2 = BitmapFactory.decodeResource(context.getResources(), R.mipmap.print_log2);
            printBitmap(bitmapLog1);
            printBitmap(bitmapLog2);
            myBinder.WriteSendData(new TaskCallback() {
                @Override
                public void OnSucceed() {
                    stateTransportQueue.offer("printPersonSuccess");
                }
                @Override
                public void OnFailed() {
                    stateTransportQueue.offer("printPersonFail");
                }
            }, new ProcessData() {
                @Override
                public List<byte[]> processDataBeforeSend() {
                    //打印头部
                    List<byte[]> list = new ArrayList<>();
                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectCharacterSize(11));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("接待号："));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(StringUtils.strTobytes(signPerson.getInvitationCode()));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());

                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectCharacterSize(8));
                    list.add(StringUtils.strTobytes("--------"));
                    list.add(DataForSendToPrinterPos58.selectCharacterSize(10));
                    list.add(StringUtils.strTobytes("嘉宾/媒体信息"));
                    list.add(DataForSendToPrinterPos58.selectCharacterSize(8));
                    list.add(StringUtils.strTobytes("--------"));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());



                    //打印签到人信息
                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("姓  名："));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(StringUtils.strTobytes(TextUtils.isEmpty(signPerson.getName())? "-":signPerson.getName()));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());

                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("证件号："));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(StringUtils.strTobytes(TextUtils.isEmpty(signPerson.getDocumentNumber())? "-":signPerson.getDocumentNumber()));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());

                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("酒  店："));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(StringUtils.strTobytes(TextUtils.isEmpty(signPerson.getHotelName())? "-":signPerson.getHotelName()));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());

                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("房  间："));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(StringUtils.strTobytes(TextUtils.isEmpty(signPerson.getRoomNumber())? "-":signPerson.getRoomNumber()));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());

                    //打印代签人信息
                    if (!TextUtils.isEmpty(presenterName)) {
                        list.add(DataForSendToPrinterPos58.printAndFeedLine());
                        list.add(DataForSendToPrinterPos58.initializePrinter());
                        list.add(DataForSendToPrinterPos58.selectCharacterSize(8));
                        list.add(StringUtils.strTobytes("--------"));
                        list.add(DataForSendToPrinterPos58.selectCharacterSize(10));
                        list.add(StringUtils.strTobytes("代签人信息"));
                        list.add(DataForSendToPrinterPos58.selectCharacterSize(8));
                        list.add(StringUtils.strTobytes("--------"));
                        list.add(DataForSendToPrinterPos58.printAndFeedLine());
                        list.add(DataForSendToPrinterPos58.printAndFeedLine());

                        list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                        list.add(StringUtils.strTobytes("姓  名："));
                        list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                        list.add(StringUtils.strTobytes(presenterName));
                        list.add(DataForSendToPrinterPos58.printAndFeedLine());

                        list.add(DataForSendToPrinterPos58.initializePrinter());
                        list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                        list.add(StringUtils.strTobytes("证件号："));
                        list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                        list.add(StringUtils.strTobytes(TextUtils.isEmpty(presenterNo) ? "-" : presenterNo));
                        list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    }

                    //打印最后的信息
                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    list.add(DataForSendToPrinterPos58.selectCharacterSize(11));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(1));
                    list.add(StringUtils.strTobytes("          欢迎您的莅临！"));
                    list.add(DataForSendToPrinterPos58.selectOrCancelBoldModel(0));
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    return list;
                }
            });
        }
        try {
            return  stateTransportQueue.take().equals("printPersonSuccess");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    private boolean printBitmap(Bitmap bitmap) {
        final Bitmap resizeBitmap =  bitmap;
        if (connected){
            myBinder.WriteSendData(new TaskCallback() {
                @Override
                public void OnSucceed() {
                    stateTransportQueue.offer("printBitmapSuccess");
                }
                @Override
                public void OnFailed() {
                    stateTransportQueue.offer("printBitmapFail");
                }
            }, new ProcessData() {
                @Override
                public List<byte[]> processDataBeforeSend() {
                    List<byte[]> list = new ArrayList<>();
                    list.add(DataForSendToPrinterPos58.initializePrinter());
                    List<Bitmap> blist = BitmapProcess.cutBitmap(resizeBitmap.getHeight(),resizeBitmap);
                    for (int i= 0 ;i<blist.size();i++){
                        list.add(DataForSendToPrinterPos58.printRasterBmp(0,
                                blist.get(i),
                                BitmapToByteData.BmpType.Threshold,
                                BitmapToByteData.AlignType.Center,
                                374));
                    }
                    list.add(DataForSendToPrinterPos58.printAndFeedLine());
                    return list;
                }
            });
        }
        try {
            return  stateTransportQueue.take().equals("printBitmapSuccess");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }
    public void release() {
        if (connected){
            myBinder.DisconnectCurrentPort(new TaskCallback() {
            @Override
            public void OnSucceed() {
                Log.i(TAG, "disconnect ok");
            }

            @Override
            public void OnFailed() {
                Log.i(TAG, "disconnect failed");
            }
            });
        }
        context.unbindService(mSerconnection);
    }
}
